package top.healthylife.gateway.platform.eye.api.util;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import top.healthylife.basics.utils.exception.BusinessException;
import top.healthylife.basics.utils.utils.SystemThreadLocal;
import top.healthylife.gateway.platform.eye.api.config.SystemConfig;
import top.healthylife.gateway.platform.eye.dto.BaseRes.EyeResBaseResultDto;
import top.heathylife.gateway.common.cons.SystemCons;
import top.heathylife.gateway.common.po.RecordRequestInfo;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * [Description] : 请求外部接口的http请求工具类
 *
 * @author : zqs
 * @version : 1.0
 * @since : 2019-12-11 15:57
 */
@Slf4j
public class OutHttpUtil {

    final static String CODE = "0";
    final static String NOT_DATA = "300000";
    public final static String[] TOKEN_WRONG = {"300002", "300003", "300009"};
    public static final String PAGE_SIZE = "pageSize";
    public static final String PAGE_NUM = "pageNum";
    final static String ERROR_CODE = "error_code";

    public static final Map<String, String> ERROR_MAP = new HashMap<>();

    static {
        ERROR_MAP.put("300000", "无数据");
        ERROR_MAP.put("300001", "请求失败");
        ERROR_MAP.put("300002", "账号失效");
        ERROR_MAP.put("300003", "账号过期");
        ERROR_MAP.put("300004", "访问频率过快");
        ERROR_MAP.put("300005", "无权限访问此api");
        ERROR_MAP.put("300006", "余额不足");
        ERROR_MAP.put("300007", "剩余次数不足");
        ERROR_MAP.put("300008", "缺少必要参数");
        ERROR_MAP.put("300009", "账号信息有误");
        ERROR_MAP.put("300010", "URL不存在");
    }

    /**
     * 发送get请求
     *
     * @param url    .
     * @param params 参数
     * @return 响应json
     */
    @SneakyThrows
    @SuppressWarnings("unchecked")
    public static <T> T get(String url, Map<String, Object> params, SystemConfig systemConfig, Class<T> cls) {
        long l1 = System.currentTimeMillis();
        String token = systemConfig.getToken();
        if (ObjectUtil.isEmpty(token)) {
            throw new BusinessException("账号token未配置");
        }
        String hide = StrUtil.hide(token, 5, token.length() - 5);
        //记录请求信息
        Map<String, String> header = new HashMap<>(2);
        header.put("Authorization", token);
        RecordRequestInfo.recordRequest(url, JSONUtil.toJsonStr(params), header, "get");
        String respContext = HttpRequest.get(url)
                .header("Authorization", token).form(params).execute().body();
        log.info("当前使用token:{}", hide);
        //将三方元数据存储到线程变量
        SystemThreadLocal.set(SystemCons.ORIGIN_DATA, respContext);
        log.info("结果返回为,Url:{},params:{},result:{}", url, JSONObject.toJSONString(params), respContext);
        long l2 = System.currentTimeMillis();
        log.info("接口模块请求第三方耗时:{}", l2 - l1);
        JSONObject jsonObject;
        try {
            jsonObject = JSONObject.parseObject(respContext);
        } catch (Exception e) {
            log.error("数据结构有异常,{}", respContext);
            throw new BusinessException("数据结构有异常");
        }
        String code = jsonObject.getString(ERROR_CODE);
        if (CODE.equals(code)) {
            //处理result为字符串的情况
            Object obj = jsonObject.get("result");
            if (obj instanceof String || obj instanceof Boolean) {
                //替换掉原来的结果集
                jsonObject.remove("result");
                Map<String, Object> map = new HashMap<>(1);
                map.put("info", obj);
                jsonObject.put("result", map);
                return jsonObject.getObject("result", cls);
            }
            //处理result为List的情况
            if (obj instanceof List) {
                //替换掉原来的结果集
                jsonObject.remove("result");
                Map<String, Object> map = new HashMap<>(1);
                map.put("list", obj);
                jsonObject.put("result", map);
                return jsonObject.getObject("result", cls);
            }
            JSONObject result = jsonObject.getJSONObject("result");
            //处理分页参数
            if (params.containsKey(PAGE_SIZE)) {
                result.put(PAGE_SIZE, params.get(PAGE_SIZE));
            }
            if (params.containsKey(PAGE_NUM)) {
                result.put(PAGE_NUM, params.get(PAGE_NUM));
            }
            return result.toJavaObject(cls);
        }
        if (NOT_DATA.equals(code)) {
            T t = cls.newInstance();
            if (t instanceof EyeResBaseResultDto) {
                EyeResBaseResultDto<?> dto = (EyeResBaseResultDto<?>) t;
                //处理分页参数
                if (params.containsKey(PAGE_SIZE) && params.get(PAGE_SIZE) != null) {
                    dto.setPageSize((Integer) params.get(PAGE_SIZE));
                }
                if (params.containsKey(PAGE_NUM) && params.get(PAGE_NUM) != null) {
                    dto.setPageNum((Integer) params.get(PAGE_NUM));
                }
                return (T) dto;
            }
            return t;
        }
        String message = ERROR_MAP.get(code);
        //token 脱敏打印,方便排查
        log.error("请求天眼查结果出错,错误原因:{},token:{},Url:{},params:{},result:{}", message, hide, url, JSONObject.toJSONString(params), respContext);
        throw new BusinessException(message);
    }

}
